home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue26 / pagectrl / PAGECTL2.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-09-02  |  5.9 KB  |  222 lines

  1. //Tabsheet can't draw buttons in bottom or right positions
  2. //Use TColorPageCtrl.TabVisible instead of
  3. //  TTabSheet.TabVisible or TTabSheet.Visible
  4.  
  5. unit PageCtl2;
  6.  
  7. interface
  8.  
  9. uses
  10.   Windows, Messages, CommCtrl, SysUtils, Classes, Graphics, Controls,
  11.   Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls;
  12.  
  13. type
  14.   TTabVPosition = (tvpNone, tvpLeft, tvpRight);
  15.   TPageControlStyle = (pcsStandard, pcsOwnerDraw);
  16.  
  17.   TODPageControl2 = class(TPageControl)
  18.   private
  19.     FCanvas       : TCanvas;
  20.     FOnDrawItem   : TDrawItemEvent;
  21.     FTabButtons   : Boolean;
  22.     FStyle        : TPageControlStyle;
  23.     FTabVPosition : TTabVPosition;
  24.  
  25.     procedure DrawItem(Index: Integer; ARect: TRect;
  26.       State: TOwnerDrawState);
  27.  
  28.   protected
  29.     procedure CreateParams(var Params: TCreateParams); override;
  30.     procedure CreateWnd; override;
  31.  
  32.     procedure SetStyle(Value: TPageControlStyle);
  33.     procedure SetTabButtons(Value: Boolean);
  34.     procedure SetTabVPosition(Value: TTabVPosition);
  35.  
  36.     procedure CNDrawItem(var Msg: TWMDrawItem);
  37.       message cn_DrawItem;
  38.  
  39.   public
  40.     constructor Create(AOwner: TComponent); override;
  41.     destructor Destroy; override;
  42.     procedure DefaultDrawTab(Index: Integer; ARect: TRect;
  43.       State: TOwnerDrawState); virtual;
  44.     property Canvas: TCanvas read FCanvas;
  45.  
  46.   published
  47.     property Style: TPageControlStyle
  48.       read FStyle write SetStyle default pcsStandard;
  49.     property TabButtons: Boolean
  50.       read FTabButtons write SetTabButtons default False;
  51.     property TabVPosition: TTabVPosition
  52.       read FTabVPosition write SetTabVPosition default tvpNone;
  53.     property OnDrawItem: TDrawItemEvent
  54.       read FOnDrawItem write FOnDrawItem;
  55.   end;
  56.  
  57. procedure Register;
  58.  
  59. implementation
  60.  
  61. //Delphi 2 and C++ Builder 1 don't have some
  62. //of the necessary constants or properties
  63. {$ifdef Ver90}
  64.   {$define OldCommCtrl}
  65. {$endif}
  66. {$ifdef Ver93}
  67.   {$define OldCommCtrl}
  68. {$endif}
  69. {$ifdef OldCommCtrl}
  70. const
  71.   tcs_Right = 2;
  72.   tcs_Bottom = 2;
  73.   tcs_Vertical = $80;
  74. {$endif}
  75.  
  76. constructor TODPageControl2.Create(AOwner: TComponent);
  77. begin
  78.   inherited;
  79.   FTabButtons   := False;
  80.   FStyle        := pcsStandard;
  81.   FTabVPosition := tvpNone
  82. end;
  83.  
  84. destructor TODPageControl2.Destroy;
  85. begin
  86.   //cleanup after ourselves
  87.   if Assigned(FCanvas) then
  88.     FCanvas.Free;
  89.   inherited
  90. end;
  91.  
  92. procedure TODPageControl2.DrawItem(Index: Integer; ARect: TRect;
  93.   State: TOwnerDrawState);
  94. begin
  95.   if Assigned(FOnDrawItem) then
  96.     FOnDrawItem(Self, Index, ARect, State)
  97.   else
  98.     DefaultDrawTab(Index, ARect, State)
  99. end;
  100.  
  101. procedure TODPageControl2.CreateParams(var Params: TCreateParams);
  102. const
  103.   ButtonStyle: array[Boolean] of LongInt = (0, tcs_Buttons);
  104.   OwnStyle: array[Boolean] of LongInt = (0, tcs_OwnerDrawFixed);
  105.   VerticalStyle: array[TTabVPosition] of LongInt =
  106.     (0, tcs_Vertical, tcs_Right or tcs_Vertical);
  107. begin
  108.   inherited;
  109.   with Params do
  110.   begin
  111.     if VerticalStyle[FTabVPosition] <> 0 then
  112.       Style := Style and not tcs_Bottom;
  113.     //When ScrollOpposite is set True, buttons don't get drawn
  114.     //Also, the control is unable to do buttons properly
  115.     //When tabs are at bottom or right
  116.     FTabButtons := FTabButtons and not
  117.       {$ifndef OldCommCtrl}
  118.       ScrollOpposite and not
  119.       {$endif}
  120.       ({$ifndef OldCommCtrl}(TabPosition = tpBottom) or {$endif}
  121.        (FTabVPosition = tvpRight));
  122.     Style := Style or ButtonStyle[FTabButtons]
  123.                    or OwnStyle[FStyle = pcsOwnerDraw]
  124.                    or VerticalStyle[FTabVPosition];
  125.    end;
  126. end;
  127.  
  128. procedure TODPageControl2.CreateWnd;
  129. begin
  130.   inherited;
  131.   //Force a realign and repositioning of tabsheets
  132.   //this is needed for the new vertical and horizontal styles
  133.   PostMessage(Handle, wm_Size, size_Restored,
  134.     MakeLong(Width, Height));
  135.   Realign
  136. end;
  137.  
  138. procedure TODPageControl2.SetStyle(Value: TPageControlStyle);
  139. begin
  140.   if Value <> FStyle then
  141.   begin
  142.     FStyle := Value;
  143.     RecreateWnd;
  144.   end;
  145. end;
  146.  
  147. procedure TODPageControl2.SetTabButtons(Value: Boolean);
  148. begin
  149.   if Value <> FTabButtons then
  150.   begin
  151.     FTabButtons := Value;
  152.     //Can't have buttons at bottom or right of control
  153.     //The Windows control can't handle it...
  154.     if Value then
  155.     begin
  156.       if FTabVPosition = tvpRight then
  157.         FTabVPosition := tvpNone;
  158.       {$ifndef OldCommCtrl}
  159.       if TabPosition = tpBottom then
  160.         TabPosition := tpTop;
  161.       {$endif}
  162.     end;
  163.     RecreateWnd;
  164.   end;
  165. end;
  166.  
  167. procedure TODPageControl2.SetTabVPosition(Value: TTabVPosition);
  168. begin
  169.   if  Value <> FTabVPosition then
  170.   begin
  171.     //When tabs are left/right, they turn into multiline
  172.     //automatically so we'd better set the MultiLine property
  173.     FTabVPosition := Value;
  174.     if Value <> tvpNone then
  175.       MultiLine := True;
  176.     RecreateWnd;
  177.   end;
  178. end;
  179.  
  180. procedure TODPageControl2.CNDrawItem(var Msg: TWMDrawItem);
  181. var
  182.   State: TOwnerDrawState;
  183. begin
  184.   if not Assigned(FCanvas) then
  185.     FCanvas := TCanvas.Create;
  186.   with Msg.DrawItemStruct^ do
  187.   begin
  188.     //The low byte of ItemState is the bitmap that our set requires
  189.     State := TOwnerDrawState(WordRec(Word(ItemState)).Lo);
  190.     FCanvas.Handle := hDC;
  191.     FCanvas.Font   := Font;
  192.     FCanvas.Brush  := Brush;
  193.     if Integer(itemID) >= 0 then
  194.       DrawItem(itemID, rcItem, State);
  195.     FCanvas.Handle := 0;
  196.   end;
  197. end;
  198.  
  199. procedure TODPageControl2.DefaultDrawTab(Index: Integer;
  200.   ARect: TRect; State: TOwnerDrawState);
  201. var
  202.   S: String;
  203.   X, Y: Integer;
  204. begin
  205.   //Do a bit of default drawing when the
  206.   //component user is'nt doing it
  207.   FCanvas.FillRect(ARect);
  208.   S := Pages[Index].Caption;
  209.   X := (ARect.Right + ARect.Left - FCanvas.TextWidth(S)) div 2;
  210.   Y := (ARect.Bottom + ARect.Top + 4 - FCanvas.TextHeight(S)) div 2;
  211.   //Active tab has text _slightly_ higher
  212.   if odSelected in State then
  213.     Dec(Y, 3);
  214.   FCanvas.TextOut(X, Y, S);
  215. end;
  216.  
  217. procedure Register;
  218. begin
  219.   RegisterComponents('Clinic', [TODPageControl2]);
  220. end;
  221.  
  222. end.